package com.example.invoker.schedule.flurry;

import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.biapp.appboard.exception.BoardException;
import com.biapp.appboard.service.schedule.AbstractSyncService;
import com.biapp.common.basic.vo.RestResponse;
import com.biapp.common.exception.BizException;
import com.biapp.common.util.HttpUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collection;
import java.util.List;
import java.util.Map;

/**
 * @Author huaiyu yin
 * @Date 2021/7/8 5:58 下午
 * @Version 1.0
 */
public abstract class FlurrySyncService extends AbstractSyncService {
    /**
     * 1.获取flurry平台数据
     * 2.验证数据
     * 3.组装完整数据
     * 4.数据处理（保存，回传等）
     */

    @Value("${flurry.baseUrl}")
    public String flurryUrl;

    @Value("${flurry.token}")
    public String flurryToken;


    /**
     * 数据同步流程流程
     *
     * @param startDate
     * @param endDate
     */
    @Transactional(rollbackFor = Exception.class)
    public void process(String startDate, String endDate) {
        List<JSONObject> result = getJSONObject(startDate, endDate);
        Collection collection = assemblyData(result);
        if (CollectionUtils.isNotEmpty(collection)) {
            save(collection);
        }
    }

    /**
     * 根据日期获取 相关的json 返回
     *
     * @param startDate
     * @param endDate
     * @return 返回相关的json数据
     */
    public List<JSONObject> getJSONObject(String startDate, String endDate) {
        this.validParam(startDate, endDate);
        String reapi = getAPI();
        Map<String, Object> paramsMap = getParamsMap();
        validation(paramsMap);
        return getFlurryData(reapi, paramsMap);
    }

    /**
     * 设置需要的属性
     *
     * @return 回传需要的ParamsMap
     * ParamsMap包括以下：
     * metrics 点击类型 （必须有）
     * dateTime 时间段区域
     * filters 拦截参数部分
     */
    public abstract Map<String, Object> getParamsMap();

    /**
     * 根据类型获取相关的api
     *
     * @return 当个类型的api
     */
    public abstract String getAPI();

    /**
     * 调用flurry平台接口
     *
     * @param api
     * @param paramsMap
     * @return 返回相关的json数据
     */
    public List<JSONObject> getFlurryData(String api, Map<String, Object> paramsMap) {
        //httpapi调用
        String result = HttpUtils.get(flurryUrl + api, flurryToken, paramsMap);
        // 返回状态
        JSONObject resultJsonObj = new JSONObject(result);
        String resultCode = resultJsonObj.getStr("code");

        if (StringUtils.isNotBlank(resultCode) && StringUtils.equals(resultCode, "400")) {
            throw new BizException(RestResponse.FAIL, "Flurry接口时间长度必须大于1");
        }
        if (StringUtils.isNotBlank(resultCode) && StringUtils.equals(resultCode, "401")) {
            throw new BizException(RestResponse.FAIL, "Flurry接口未授权");
        }
        if (StringUtils.isNotBlank(resultCode) && StringUtils.equals(resultCode, "403")) {
            throw new BizException(RestResponse.FAIL, "Flurry接口无权访问");
        }
        if (StringUtils.isNotBlank(resultCode) && StringUtils.equals(resultCode, "404")) {
            throw new BizException(RestResponse.FAIL, "Flurry接口访问不存在");
        }

        // 回传json数据
        return JSONUtil.toList(resultJsonObj.getStr("rows"), JSONObject.class);
    }


    //数据  获取  组装  逻辑处理 todo

    /**
     * 数据  获取  组装  逻辑处理 todo
     *
     * @param jsonObjectList
     * @return 返回封装的list
     */
    public abstract Collection assemblyData(List<JSONObject> jsonObjectList);

    @Override
    public void assemblyData() {

    }


    //获取数据合法验证   todo  预留可能存在在数据问题的修正
    @Override
    public void validation() {

    }

    public void validation(Map<String, Object> paramsMap) {
        if (null == paramsMap) {
            throw new BoardException("Flurry接口参数 paramsMap 不存在");
        }
    }

}
